﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Xml.Linq;
using Lightray.Hattrick.ChppLib;
using Lightray.Hattrick.ChppLib.EntityTypes;

namespace Lightray.Hattrick
{
    public class YouthTeamModel : BaseTeamModel
    {
        private EntityCollection<YouthPlayer> _oldPlayers, _currentPlayers;

        private DataTable _dataSource;

        #region DataTable columns

        private const string COL_TIME_UNTIL_PROMOTION = "PROMOTE";
   

        #endregion
                    
        public override bool HasProgressReport
        {
            get { return pastWeekDataAvailable(); }
        }

        public YouthTeamModel(ITrickStorageEntry newEntry, ITrickStorageEntry oldEntry)
        {
            _currentPlayers = instancePlayers(newEntry.MyYouthPlayers);
            _oldPlayers = instancePlayers(oldEntry.MyYouthPlayers);

            if (minimalDataAvailable())
                workData();
        }

        public override ModelColumnDescription GetColumnDescription(string columnName)
        {
            switch (columnName)
            {
                case COL_TIME_UNTIL_PROMOTION:
                    return ModelColumnDescription.TimeUntilPromotion;
            }

            return base.GetColumnDescription(columnName);
        }

        public override PlayerRole GetRoleColumnName(string columnName)
        {
            throw new NotImplementedException();
        }

        public override string[] UnlockedSkillsFromRow(DataRowView dataRowView)
        {            
            YouthPlayer player = PlayerFromRow(dataRowView) as YouthPlayer;
            if (!player.HasUnlockedSkills)
                return null;

            return (from Skill s in Enum.GetValues(typeof(Skill))
                    where player.PotentialSkillUnlocked(s) || player.SkillUnlocked(s)
                    select columnNameFromSkill(s)).ToArray();
        }

        private EntityCollection<YouthPlayer> instancePlayers(XDocument xml)
        {
            return xml != null ? YouthPlayer.FromXml(xml) : null;
        }

        private bool minimalDataAvailable()
        {
            return _currentPlayers != null;
        }

        private bool pastWeekDataAvailable()
        {
            return _oldPlayers != null;
        }

        private void workData()
        {
            buildDataSource();
            fillDataSource();
            buildProgressReport();
            Data = new DataView(_dataSource);
        }

        private void buildProgressReport()
        {
            if (pastWeekDataAvailable())
                _progressReport = ProgressReport.GetTeamProgressReport(_currentPlayers, _oldPlayers);
        } 

        private void buildDataSource()
        {
            _dataSource = new DataTable();
            _dataSource.Columns.AddRange(new DataColumn[] 
            {
                new DataColumn(COL_NAME,  typeof(string)),
                new DataColumn(COL_AGE,   typeof(HattrickAge)),                
                new DataColumn(COL_TIME_UNTIL_PROMOTION,   typeof(TimeSpan)),                
                new DataColumn(COL_CARDS, typeof(int)),
                new DataColumn(COL_INJURY,   typeof(int)),
                new DataColumn(COL_SCORING,   typeof(YouthPlayerSkill)),                
                new DataColumn(COL_PLAYMAKING,    typeof(YouthPlayerSkill)),
                new DataColumn(COL_WINGER,   typeof(YouthPlayerSkill)),                
                new DataColumn(COL_PASSING,   typeof(YouthPlayerSkill)),                
                new DataColumn(COL_DEFENDING,   typeof(YouthPlayerSkill)),                
                new DataColumn(COL_KEEPING,    typeof(YouthPlayerSkill)),                
                new DataColumn(COL_SETPIECES,    typeof(YouthPlayerSkill)),                        
                new DataColumn(COL_SPECIALITY,   typeof(Specialty)),
                new DataColumn(COL_PLAYER_INSTANCE, typeof(BasicPlayer)),
            });
        }

        private void fillDataSource()
        {
            _dataSource.BeginLoadData();
            foreach (var player in _currentPlayers)
            {
                _dataSource.Rows.Add(   player.Name,
                                        player.Age,
                                        player.CanBePromotedTime,
                                        player.Cards,
                                        player.InjuryLevel,
                                        new YouthPlayerSkill(player.Scoring, player.ScoringPotential),
                                        new YouthPlayerSkill(player.Playmaking, player.PlaymakingPotential),
                                        new YouthPlayerSkill(player.Winger, player.WingerPotential),
                                        new YouthPlayerSkill(player.Passing, player.PassingPotential),
                                        new YouthPlayerSkill(player.Defending, player.DefendingPotential),
                                        new YouthPlayerSkill(player.Keeper, player.KeeperPotential),
                                        new YouthPlayerSkill(player.SetPieces, player.SetPiecesPotential),                                   
                                        player.Specialty,
                                        player);
            }
            _dataSource.EndLoadData();
        }

        private string columnNameFromSkill(Skill s)
        {
            switch (s)
            {                
                case Skill.Keeper:
                    return COL_KEEPING;
                case Skill.Playmaking:
                    return COL_PLAYMAKING;
                case Skill.Scoring:
                    return COL_SCORING;
                case Skill.Passing:
                    return COL_PASSING;
                case Skill.Winger:
                    return COL_WINGER;
                case Skill.Defending:
                    return COL_DEFENDING;
                case Skill.SetPieces:
                    return COL_SETPIECES;
            }   

            return string.Empty;
        }
    }
}
